package com.jfinal.enjoy.lexer;

import com.intellij.lexer.FlexLexer;
import com.intellij.psi.tree.IElementType;
import static com.jfinal.enjoy.psi.EnjoyTypes.*;

%%

%class EnjoyFlexLexer
%implements FlexLexer
%unicode
%public
%function advance
%type IElementType
%states LINE_COMMENT, COMMENT_BLOCK, OUTPUT


%%

<YYINITIAL> {
  // 注释开始
  "#--"              { yybegin(COMMENT_BLOCK); return BLOCK_COMMENT_START; }
  "###"              { yybegin(LINE_COMMENT); return LINE_COMMENT_START; }

  // 输出表达式开始
  "#("               { yybegin(OUTPUT); return OUTPUT_START; }

  // 指令
  "#else if"          { return ELSEIF; }
  "#else"            { return ELSE; }
  "#if"              { return IF; }
  "#for"             { return FOR; }
  "#set"             { return SET; }
  "#define"          { return DEFINE; }
  "#include"         { return INCLUDE; }
  "#switch"          { return SWITCH; }
  "#case"            { return CASE; }
  "#default"         { return DEFAULT; }
  "#end"             { return END; }

  // 符号
  "("                { return LPAREN; }
  ")"                { return RPAREN; }
  ","                { return COMMA; }
  ":"                { return COLON; }
  "."                { return DOT; }

  // 运算符
  "+"|"-"|"*"|"/"    { return BINARY_OP; }
  "=="|"!="|"<"|">"|"<="|">=" { return COMPARE_OP; }
  "&&"               { return LOGIC_OP; }
  "||"               { return LOGIC_OP; }

  // 字面量
  \"([^\"\\\n]|\\.)*\" { return STRING_LITERAL; }
  [0-9]+             { return NUMBER; }
  "true"|"false"     { return BOOLEAN; }
  "null"             { return NULL; }

  // 标识符
  [a-zA-Z_][a-zA-Z0-9_]* { return IDENT; }

  // 换行
  "\r\n"             { return NEWLINE; }
  "\n"               { return NEWLINE; }

  // 普通文本（不包含#及换行）
  [^#\r\n]+          { return ENJOY_TEXT; }

  // 单独的 # 字符当做文本
  "#"                { return ENJOY_TEXT; }
}

<LINE_COMMENT> {
  [^\n\r]*           { yybegin(YYINITIAL); return LINE_COMMENT_CONTENT; }
}

<COMMENT_BLOCK> {
  "--#"              { yybegin(YYINITIAL); return BLOCK_COMMENT_END; }
  [^-]+              { return BLOCK_COMMENT_CONTENT; }
  "-"                { return BLOCK_COMMENT_CONTENT; }
}

<OUTPUT> {
  [^)]+              { return JAVA_EXPR; }
  ")"                { yybegin(YYINITIAL); return RPAREN; }
}
